package com.ftg.learn.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ftg.learn.entity.StudentEntity;
import com.ftg.learn.mapper.StudentMapper;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.apache.ibatis.exceptions.ExceptionFactory;
import org.apache.ibatis.executor.*;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.*;
import org.apache.ibatis.session.defaults.DefaultSqlSession;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.activation.DataSource;
import java.sql.SQLException;
import java.util.List;

/**
 * 学生业务处理
 *
 * id 默认为 StudentService 首字母小写  studentService
 *
 *
 * @author kangjx
 * @version 1.0
 * @date 2023/9/8 上午9:17
 */
@Service(value = "aa")
public class StudentService {

    @Autowired
    StudentMapper studentMapper;

    /**
     * 分页方法
     *
     * @param name    姓名
     * @param current 页码
     * @param limit   条数
     * @param ipage   返回信息
     */
    public void pageWithName(String name, Integer current, Integer limit, IPage<StudentEntity> ipage) {
        ipage.setRecords(studentMapper.showAll(name, (current - 1) * limit, limit));
        ipage.setTotal(studentMapper.countShowAll(name));
    }

//    Transactional  私有方法
//      try catch()

    @Transactional(rollbackFor = Exception.class)
    public int insertStudent(StudentEntity se) {
        return studentMapper.insertStudent(se);
    }

    public StudentEntity findone(String sno) {
        return studentMapper.findone(sno);
    }


    public static void main(String[] args) {

        MysqlDataSource dataSource = new MysqlDataSource();

        TransactionFactory transactionFactory = new JdbcTransactionFactory();

        Environment environment = new Environment("development", transactionFactory, dataSource);

        Configuration configuration = new Configuration(environment);

        configuration.addMapper(StudentMapper.class);


//        SqlSessionFactoryBuilder 返回了一个sqlsessionfactory的实现类 DefaultSqlSessionFactory

        //通过构造方法 把 上述的 configuration传递给了  DefaultSqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);


//调用的sqlsession 接口的实现类里面的方法 DefaultSqlSessionFactory  openSession();

        //有几个执行器  (3 4 )....
        //解译一下 openSessionFromDataSource (三个)
        /**
         * Executor 执行器
         * @param ExecutorType 执行器类型
         *       SIMPLE, 简单  (默认)
         *       REUSE,  可重复利用的
         *       BATCH   批量操作
         *    CachingExecutor  缓存执行器 国 select * from student 王 （快了）
         *
         *   缓存机制 :  1 2
         *
         * @param TransactionIsolationLevel 事务传播机制 4
         *
         */
//        private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
//            Transaction tx = null;
//            try {
//                //环境
//                final Environment environment = configuration.getEnvironment();
//                //事务工厂
//                final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//
//                //创建事务  数据源  传播  false
//                tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//
//                //执行器
//                final Executor executor = configuration.newExecutor(tx, execType);
//                return new DefaultSqlSession(configuration, executor, autoCommit);
//            } catch (Exception e) {
//                closeTransaction(tx); // may have fetched a connection so lets call close()
//                throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
//            } finally {
//                ErrorContext.instance().reset();
//            }
//        }
//
//
//
//        public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
//            executorType = ExecutorType.SIMPLE ;
//            Executor executor;
//
//            executor = new SimpleExecutor(this, transaction);
//
//            executor = (Executor) interceptorChain.pluginAll(executor);
//            return executor;
//        }

//        MappedStatement  里面存储就是你写的xml里面的sql语句，或者接口里面的方法 上面的sql语句


        SqlSession session = sqlSessionFactory.openSession(ExecutorType.REUSE,TransactionIsolationLevel.SERIALIZABLE);

//        session.insert();

        //mybatis 持久层 o(java table)rm(sqlmapper)  缓存 (sqlsession --- MappedStatement --- (xml 接口里面映射信息 [sql]))

    }

}
